#!/usr/bin/env python3
"""
错误处理机制演示

展示XCQuant框架中增强的错误处理功能
"""

import asyncio
import sys
import os
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from xcquant.core.error_handler import error_handler, handle_errors, ErrorSeverity
from xcquant.core.exceptions import (
    ExchangeAPIError, DataMissingError, StrategyError, 
    RiskControlError, NetworkError
)
from xcquant.core.helpers import retry, smart_retry, timeout, safe_execute_async
from xcquant.core import unified_logger


# 获取日志记录器
logger = unified_logger.get_logger(__name__)


class ErrorHandlingDemo:
    """错误处理演示类"""
    
    def __init__(self):
        self.demo_count = 0
        
        # 注册错误回调
        error_handler.register_error_callback(self._error_callback)
    
    def _error_callback(self, error_context):
        """错误回调函数"""
        logger.info(f"错误回调触发: {error_context.error}")
    
    @handle_errors(component="ErrorDemo", operation="simulate_api_error")
    async def simulate_api_error(self):
        """模拟API错误"""
        logger.info("模拟交易所API错误...")
        raise ExchangeAPIError(
            "API调用失败", 
            exchange="binance", 
            api_endpoint="/api/v3/ticker/price",
            http_status=429
        )
    
    @handle_errors(component="ErrorDemo", operation="simulate_data_error")
    async def simulate_data_error(self):
        """模拟数据错误"""
        logger.info("模拟数据缺失错误...")
        raise DataMissingError(
            "K线数据缺失",
            symbol="BTCUSDT",
            period="1h",
            date_range="2024-01-01 to 2024-01-02"
        )
    
    @handle_errors(component="ErrorDemo", operation="simulate_risk_error")
    async def simulate_risk_error(self):
        """模拟风险控制错误"""
        logger.info("模拟风险控制错误...")
        raise RiskControlError(
            "触发风险控制",
            risk_type="position_limit",
            risk_level="critical",
            triggered_rules=["max_position_size", "daily_loss_limit"]
        )
    
    @retry(max_attempts=3, delay=0.5, jitter=True)
    async def unstable_network_operation(self):
        """不稳定的网络操作"""
        self.demo_count += 1
        logger.info(f"尝试网络操作 (第{self.demo_count}次)")
        
        if self.demo_count < 3:
            raise NetworkError("网络连接超时", url="https://api.binance.com")
        
        logger.info("网络操作成功!")
        return "操作成功"
    
    @smart_retry(network_errors=3, api_errors=2)
    async def smart_retry_demo(self):
        """智能重试演示"""
        self.demo_count += 1
        logger.info(f"智能重试演示 (第{self.demo_count}次)")
        
        if self.demo_count == 1:
            raise NetworkError("网络错误")
        elif self.demo_count == 2:
            raise ExchangeAPIError("API错误", exchange="binance")
        
        logger.info("智能重试成功!")
        return "智能重试成功"
    
    @timeout(2.0)
    async def timeout_demo(self):
        """超时演示"""
        logger.info("开始超时演示...")
        await asyncio.sleep(3.0)  # 故意超时
        return "不应该到达这里"
    
    async def safe_execution_demo(self):
        """安全执行演示"""
        logger.info("安全执行演示...")
        
        # 安全执行可能失败的函数
        result = await safe_execute_async(
            self.risky_operation,
            default="默认值",
            logger=logger
        )
        
        logger.info(f"安全执行结果: {result}")
        return result
    
    async def risky_operation(self):
        """可能失败的操作"""
        raise ValueError("这是一个故意的错误")
    
    async def run_all_demos(self):
        """运行所有演示"""
        logger.info("=" * 60)
        logger.info("错误处理机制演示开始")
        logger.info("=" * 60)
        
        demos = [
            ("API错误处理", self.simulate_api_error),
            ("数据错误处理", self.simulate_data_error),
            ("风险控制错误", self.simulate_risk_error),
            ("重试机制", self.unstable_network_operation),
            ("智能重试", self.smart_retry_demo),
            ("超时处理", self.timeout_demo),
            ("安全执行", self.safe_execution_demo),
        ]
        
        for demo_name, demo_func in demos:
            logger.info(f"\n--- {demo_name} ---")
            try:
                result = await demo_func()
                logger.info(f"演示结果: {result}")
            except Exception as e:
                logger.error(f"演示失败: {e}")
            
            # 重置计数器
            self.demo_count = 0
            
            # 等待一下
            await asyncio.sleep(1)
        
        # 显示错误统计
        logger.info("\n--- 错误统计 ---")
        stats = error_handler.get_error_statistics()
        for key, value in stats.items():
            logger.info(f"{key}: {value}")
        
        logger.info("=" * 60)
        logger.info("错误处理机制演示结束")
        logger.info("=" * 60)


async def main():
    """主函数"""
    try:
        demo = ErrorHandlingDemo()
        await demo.run_all_demos()
        
    except KeyboardInterrupt:
        logger.info("演示被用户中断")
    except Exception as e:
        logger.error(f"演示过程中发生错误: {e}")
    finally:
        # 清理错误历史
        error_handler.clear_error_history()
        logger.info("演示清理完成")


if __name__ == "__main__":
    # 运行演示
    asyncio.run(main())